package com.sun.temp.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.CharsetUtil;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

/**
 * Created by gantianxing on 2017/7/20.
 */
//@Component
//public class NettyManager {
//    private static final Log log = LogFactory.getLog(NettyManager.class);
//    private ScheduledExecutorService executorReConService;
//    private ScheduledExecutorService executorTaskService;
//    @Resource
//    private NettyClientHandler handler;
//    @Resource
//    private NettyProperties nettyProperties;
//
//    /**
//     * netty服务启动方法
//     */
//    @PostConstruct
//    public void init(){
//
//        //建立连接
//        this.connectServers();
//        //启动定时节点获取worker
////        this.taskReq();
//        //启动重连worker
//        this.reConnect();
//    }
//
//
//    /**
//     * netty服务销毁方法
//     */
//    @PreDestroy
//    public void destroy(){
//        this.relaseAll();
//    }
//
////    --------------------wujian--------------------------------------
//
//    /**
//     * 遍历服务器列表，建立长连接
//     */
//    public void connectServers(){
//        if(null==nettyProperties.getUrl() || nettyProperties.getUrl().size()==0){
//            return;
//        }
//        nettyProperties.getUrl().forEach(url->{
//            regToServer(url);
//        });
//    }
//
//
//    /**
//     * 检查服务列表,把新的服务放入重连map
//     * @param serverInfo 格式serverId:serverPort
//     */
//    private void regToServer(String serverInfo){
//        //step1 检查serverInfo是否已经在 有效的server map里
//        if(NettyServerMap.getValid(serverInfo)!=null){ return ; }
//
//        //step2与服务端建立连接
//        if(NettyServerMap.getInvalid(serverInfo) == null){
//            String oneServer [] = serverInfo.split("\\:");
//            String ip = oneServer[0];
//            int port = Integer.valueOf(oneServer[1]).intValue();
//            NettyEntity nettyClient = new NettyEntity(port,ip,handler,nettyProperties);
//            nettyClient.connect();
//            //连接成功方有效map，否则放无效map
//            if(nettyClient.channel == null){
//                NettyServerMap.addInValid(serverInfo, nettyClient);
//            }else {
//                NettyServerMap.addValid(serverInfo, nettyClient);
//            }
//        }
//    }
//
//    /**
//     * 定时重链接无效的服务器列表
//     */
//    public void reConnect(){
//        executorReConService = Executors.newScheduledThreadPool(1);
//        executorReConService.scheduleWithFixedDelay(new Runnable() {
//            public void run() {
//                try {
//                    Map<String, NettyEntity> invalid = NettyServerMap.getAllInvalid();
//                    for (String key : invalid.keySet()) {
//                        NettyEntity clientInfo = invalid.get(key);
//                        clientInfo.connect();
//
//                        //连接成功后
//                        if (clientInfo.channel != null) {
//                            NettyServerMap.removeInvalid(key);
//                            NettyServerMap.addValid(key, clientInfo);
//                        }
//                    }
//                }catch (Exception e){
//                    log.error("定时重连失败",e);
//                }
//            }
//        }, 0, nettyProperties.getReconnectWaitSecond(), TimeUnit.SECONDS);
//    }
//
//
//    /**
//     * 定时随机取一台有效的服务器发起请求
//     */
//    public void taskReq() {
//        executorTaskService = Executors.newScheduledThreadPool(1);
//        executorTaskService.scheduleWithFixedDelay(new Runnable() {
//            public void run() {
//                try{
//                    NettyEntity nettyClient = NettyServerMap.getRandomChannl();
//                    if(nettyClient!=null){
//                        if (nettyClient.channel != null) {
//                            log.info("random send task.server address:"+nettyClient.channel.remoteAddress());
//                            nettyClient.channel.writeAndFlush("重新连接");
//                        }
//                    }else
//                    {
//                        log.error("没有可用的服务");
//                    }
//                } catch (Exception e){
//                    log.error("定时发起task任务失败",e);
//                }
//            }
//        }, nettyProperties.getTaskRequestWaitTime(), nettyProperties.getTaskRequestWaitTime(), TimeUnit.SECONDS);
//    }
//
//    /**
//     * 释放资源
//     */
//    public void relaseAll(){
//        Map<String, NettyEntity> valid = NettyServerMap.getAllValid();
//        for(String key: valid.keySet()){
//            NettyEntity clientInfo = valid.get(key);
//            if(clientInfo.channel !=null){
//                clientInfo.releaseConnect();
//            }
//        }
//
//        Map<String, NettyEntity> invalid = NettyServerMap.getAllInvalid();
//        for(String key: invalid.keySet()){
//            NettyEntity clientInfo = invalid.get(key);
//            if(clientInfo.channel !=null){
//                clientInfo.releaseConnect();
//            }
//        }
//    }
//
////    --------------------wujian--------------------------------------
//
//    public static class NettyEntity {
//        private static final Log log = LogFactory.getLog(NettyEntity.class);
//        private int port;
//        private String host;
//        private EventLoopGroup group;
//        Bootstrap bootstrap;
//        public Channel channel;
//        private NettyClientHandler businessHander;
//        private NettyProperties nettyProperties;
//
//        public NettyEntity(int port, String host, NettyClientHandler businessHander, NettyProperties nettyProperties){
//            this.host = host ;
//            this.port = port ;
//            this.businessHander = businessHander;
//            this.nettyProperties = nettyProperties;
//            group = new NioEventLoopGroup();
//            bootstrap = new Bootstrap();
//            bootstrap.channel(NioSocketChannel.class);
//            bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
//            bootstrap.group(group);
//            bootstrap.handler(new ChildChannelHandler(nettyProperties,businessHander));
//        }
//
//        /**
//         * 连接服务器
//         */
//        public void connect() {
//            try {
//                // 连接服务端
//                if (channel != null && channel.isOpen()) {
//                    channel.close();
//                }
//                ChannelFuture future = bootstrap.connect(host, port).sync();
//                channel = future.channel();
//
//                // 此方法会阻塞
//                //channel.closeFuture().sync();
//                if (future.isSuccess()) {
//                    log.info("connect server success-" + channel.remoteAddress());
//
////                    channel.writeAndFlush();
//                    log.info("login,server address-" + channel.remoteAddress());
//                }
//
//            } catch (Exception e) {
//                log.error("connect server failed-"+host+":"+port);
//                if (channel != null && channel.isOpen()) {
//                    channel.close();
//                }
//                channel = null;
//            }
//        }
//        /**
//         * 断开链接，释放资源
//         */
//        public void releaseConnect(){
//            if(channel!=null&&channel.isOpen()){
//                log.info("releaseConnect,server address:" + channel.remoteAddress());
//                channel.close();
//            }
//            if(group!=null){
//                group.shutdownGracefully();
//            }
//
//        }
//
//        public NettyProperties getNettyProperties() {
//            return nettyProperties;
//        }
//    }
//
//    private static class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
//        private NettyProperties nettyProperties;
//        private NettyClientHandler businessHander;
//        public ChildChannelHandler(NettyProperties nettyProperties, NettyClientHandler businessHander) {
//            super();
//            this.nettyProperties = nettyProperties;
//            this.businessHander = businessHander;
//        }
//        @Override
//        protected void initChannel(SocketChannel socketChannel) throws Exception {
////            socketChannel.pipeline().addLast(new ObjectEncoder());
////            socketChannel.pipeline().addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
//            socketChannel.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
//            socketChannel.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
//            socketChannel.pipeline().addLast(new IdleStateHandler(nettyProperties.getReadWaitSecond(), nettyProperties.getWriteWaitSecond(), 0, TimeUnit.SECONDS));
//            socketChannel.pipeline().addLast(businessHander);
//        }
//    }
//}
